package dao

import (
	"fmt"
	"service/app/dto"
	"service/app/mode"

	"gorm.io/gorm"
)

type RoleDao struct {
	BaseDao
}

var roleDao *RoleDao

func RoleDaoInit() *RoleDao {
	if roleDao == nil {
		roleDao = &RoleDao{
			BaseDao: newBaseDao(),
		}
	}
	return roleDao
}

/**  从角色获取列表perm列表*/
func (m *RoleDao) Role_permListD(id *dto.ReqUriIdDto) (*[]mode.Db_menu, error) {
	var rolePermList mode.Db_roles
	err := m.Orm.Preload("Perm").Take(&rolePermList, "id = ?", id.Id).Error
	if err != nil {
		return nil, err
	}
	var permlist dto.Ipm_pmUrlList
	//todo 关联api_id是否合适,现在暂时以path关联
	// var permlist dto.ImenuList_updata
	// for _, v := range rolePermList.Perm {
	// 	permlist.Menus = append(permlist.Menus, int(v.ID))
	// }
	// menuList, err := menuDao.MenusByIdsD(&permlist)
	for _, v := range rolePermList.Perm {
		permlist.Pm = append(permlist.Pm, v.Fullpath)
	}
	menuList, err := menuDao.MenusByUrlD(&permlist)
	if err != nil {
		return nil, err
	}
	return menuList, nil
}

/**  从角色更新列表perm列表*/
func (m *RoleDao) RoleUpdataPermD(id *dto.ReqUriIdDto, permList *dto.Ipm_pmIntList) (*[]mode.Db_pm, error) {
	var role = mode.Db_roles{Model: gorm.Model{ID: uint(id.Id)}}
	var updataList []mode.Db_pm
	if err := m.Orm.Model(&mode.Db_pm{}).Where("id in ?", permList.Pm).Find(&updataList).Error; err != nil {
		return nil, fmt.Errorf("未找到perm列表中的部分参数,%v", err.Error())
	}
	if err := m.Orm.Model(&role).Association("Perm").Replace(&updataList); err != nil {
		return nil, fmt.Errorf("未找到perm列表中的部分参数,%v", err.Error())
	}
	return &updataList, nil
}

/**  从角色列表中获取权限列表*/
func (m *RoleDao) RolesPermD(roleList *dto.IroleUdataList) (*[]mode.Db_pm, error) {
	var list []mode.Db_roles
	var roles []uint
	for _, v := range roleList.Roles {
		roles = append(roles, uint(v.ID))
		// roles = append(roles, mode.Db_roles{Model: gorm.Model{ID: uint(v.ID)}})
	}
	// todo 优化查找方法,不加载角色参数,直返回permlist
	err := m.Orm.Preload("Perm").Find(&list, "id in ?", roles).Error
	if err != nil {
		return nil, err
	}
	var newList []mode.Db_pm
	for _, v := range list {
		if len(v.Perm) > 0 {
			newList = m.BaseDao.RmMenuduplicates(newList, v.Perm)
		}
	}
	return &newList, nil
}

// TEST pm中获取role
// func (m *RoleDao) RolesPermD(roleList *dto.IroleUdataList) (*[]mode.Db_pm, error) {
// 	var list []mode.Db_pm
// 	var roles []uint
// 	for _, v := range roleList.Roles {
// 		roles = append(roles, uint(v.ID))
// 		// roles = append(roles, mode.Db_roles{Model: gorm.Model{ID: uint(v.ID)}})
// 	}
// 	err := m.Orm.Preload("Perm").Find(&list, "id in ?", []uint{127, 128}).Error
// 	if err != nil {
// 		return nil, err
// 	}
// 	return &list, nil
// 	// err := m.Orm.Model(&mode.Db_roles{}).Where("id in ?",[1,2]).Find(&list)
// }

/**  like,分页 搜索功能  已过滤用户密码*/
func (m *RoleDao) RoleAndUsersD(paginat *dto.ReqPaginat) (*[]mode.IresUserList, int64, error) {
	var UserList []mode.IresUserList
	var total int64
	// 数据库联查

	err := m.Orm.Model(&mode.Lz_user{}).Preload("Roles").Count(&total).
		Scopes(paginat.PaginatFn(m.Orm)).Find(&UserList).Error
	return &UserList, total, err
}

func (m *RoleDao) RoleAddD(param *dto.RoleAdd) error {
	db_role := mode.Db_roles{
		Name:    param.Name,
		Desc:    param.Desc,
		Disable: 1,
	}
	return m.Orm.Save(&db_role).Error
}

func (m *RoleDao) RoleListD() (*[]mode.Db_roles, error) {
	var list []mode.Db_roles
	err := m.Orm.Model(&mode.Db_roles{}).Find(&list).Error
	if err != nil {
		return nil, err
	}
	return &list, nil
}

func (m *RoleDao) RoleList_userIdD(id int) ([]mode.Db_roles, error) {
	user := &mode.Lz_user{
		Model: gorm.Model{ID: uint(id)},
	}
	var roles []mode.Db_roles
	err := m.Orm.Model(&user).Association("Roles").Find(&roles)
	if err != nil {
		return nil, err
	}
	return roles, nil
}
func (m *RoleDao) Role_userId_addD(id int, roles []int) error {
	user := &mode.Lz_user{
		Model: gorm.Model{ID: uint(id)},
	}
	var addList []mode.Db_roles
	for _, v := range roles {
		addList = append(addList, mode.Db_roles{Model: gorm.Model{ID: uint(v)}})
	}
	return m.Orm.Model(user).Association("Roles").Append(&addList)
}

func (m *RoleDao) Role_userId_delD(id int, roles []int) error {
	user := &mode.Lz_user{
		Model: gorm.Model{ID: uint(id)},
	}
	var addList []mode.Db_roles
	for _, v := range roles {
		addList = append(addList, mode.Db_roles{Model: gorm.Model{ID: uint(v)}})
	}
	return m.Orm.Model(user).Association("Roles").Delete(&addList)
}
